﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Gamelight.Graphics
{
	public enum FontStyle
	{
		Normal = 0x00,
		Bold = 0x01,
		Italic = 0x02,
		Underline = 0x04,
		BoldItalic = 0x03,
		BoldUnderline = 0x05,
		ItalicUnderline = 0x06,
		BoldItalicUnderline = 0x7
	}

	public static class Text
	{
		private static Dictionary<string, Image> textCache = new Dictionary<string, Image>();

		internal static void ClearTextCache()
		{
			textCache.Clear();
		}

		private static string GetCacheIdFromInput(string text, string fontName, double fontSize, Color color, FontStyle style)
		{
			return fontName + "|" + color.Alpha.ToString() + "|" + color.Red.ToString() + "|" + color.Green.ToString() + "|" + color.Blue.ToString() + "|" + fontSize.ToString() + "|" + style.ToString() + "|" + text;
		}

		public static Image GenerateImageForText(string text, string fontName, double fontSize, Color color)
		{
			return Text.Create(text, fontName, fontSize, color, FontStyle.Normal);
		}

		public static Image Create(string text, string fontName, double fontSize, Color color, FontStyle fontStyle)
		{
			string id = GetCacheIdFromInput(text, fontName, fontSize, color, fontStyle);

			Image image = null;

			if (textCache.TryGetValue(id, out image))
			{
				return new Image(image);
			}
			TextBlock textBlock = new TextBlock()
			{
				FontFamily = new FontFamily(fontName),
				Text = text,
				FontSize = fontSize
			};
			bool doBold = (fontStyle & FontStyle.Bold) > 0;
			bool doItalic = (fontStyle & FontStyle.Italic) > 0;
			bool doUnderline = (fontStyle & FontStyle.Underline) > 0;
			textBlock.FontWeight = doBold ? FontWeights.ExtraBold : FontWeights.Normal;
			textBlock.FontStyle = doItalic ? System.Windows.FontStyles.Italic : System.Windows.FontStyles.Normal;

			textBlock.Foreground = new SolidColorBrush(System.Windows.Media.Color.FromArgb(color.Alpha, color.Red, color.Green, color.Blue));

			int width = (int)textBlock.ActualWidth;
			int height = (int)textBlock.ActualHeight;
			WriteableBitmap bmp = new WriteableBitmap(textBlock, null);
			image = new Image(bmp);
			Image cropped = new Image(width + 1, height + 4);
			cropped.Blit(image, 0, 0);
			if (doUnderline)
			{
				Draw.Rectangle(cropped, color, 0, cropped.Height - 6, cropped.Width, doBold ? 2 : 1);
			}
			textCache.Add(id, cropped);
			return new Image(cropped);
		}
	}
}
